/*
 * @project-name webadmin
 * @Description: 
 * @author lenovo
 * @date 2021/6/10 14:09
 * @file whrflow
*/

import {Graph , Addon ,FunctionExt,Node,Shape} from "@antv/x6";
import './shapes'

export class Whrflow {
    /**
     * 配置信息
     * @param options：Object（graph，stencil）
     */
    constructor(options) {
        this.options = options
        this.edgeColor = '#8b8b8b'
        this.options.graph.connecting.createEdge = function(){
            return new Shape.Edge({
                attrs: {
                    wrap: {
                        connection: true,
                        strokeWidth: 10,
                        strokeLinejoin: 'round',
                    },
                    line: {
                        // strokeDasharray: '5 5',
                        stroke: this.edgeColor,
                        strokeWidth: 1,
                        targetMarker: {
                            name: 'classic',
                            size: 8
                        }
                    },
                },

                router: {
                    name: 'manhattan'
                },
                zIndex: 0
            })
        },
        this.init_graph()
        this.init_stencil()
        this.init_shapes()
        this.initEvent()
    }

    init_graph() {
        this.graph = new Graph(this.options.graph);
        this.graph.centerContent()
    }

    /**
     * 初始化侧边栏
     */
    init_stencil(){
        this.options.stencil.target = this.graph
        this.stencil = new Addon.Stencil(this.options.stencil)
        this.options.stencil.container.appendChild(this.stencil.container)
    }
    init_shapes(){
        const {graph} = this
        const r1 = graph.createNode({
            shape: 'flow-chart-rect',
            attrs: {
                body: {
                    rx: 24,
                    ry: 24
                },
                text: {
                    textWrap: {
                        text: '起始节点'
                    }
                }
            }
        })
        const r2 = graph.createNode({
            shape: 'flow-chart-rect',
            attrs: {
                text: {
                    textWrap: {
                        text: '流程节点'
                    }
                }
            }
        })
        const r3 = graph.createNode({
            shape: 'flow-chart-rect',
            width: 52,
            height: 52,
            angle: 45,
            attrs: {
                'edit-text': {
                    style: {
                        transform: 'rotate(-45deg)'
                    }
                },
                text: {
                    textWrap: {
                        text: '判断节点'
                    },
                    transform: 'rotate(-45deg)'
                }
            },
            ports: {
                groups: {
                    top: {
                        position: {
                            name: 'top',
                            args: {
                                dx: -26
                            }
                        }
                    },
                    right: {
                        position: {
                            name: 'right',
                            args: {
                                dy: -26
                            }
                        }
                    },
                    bottom: {
                        position: {
                            name: 'bottom',
                            args: {
                                dx: 26
                            }
                        }
                    },
                    left: {
                        position: {
                            name: 'left',
                            args: {
                                dy: 26
                            }
                        }
                    }
                }
            }
        })
        const r4 = graph.createNode({
            shape: 'flow-chart-rect',
            width: 70,
            height: 70,
            attrs: {
                body: {
                    rx: 35,
                    ry: 35
                },
                text: {
                    textWrap: {
                        text: '链接节点'
                    }
                }
            }
        })
        this.stencil.load([r1, r2, r3, r4], 'easy_nodes')
    }
    initEvent () {
        const { graph ,edgeColor} = this
        const container = this.options?.graph?.container

        graph.on('node:dblclick', ({ cell, view }) => {
            const oldText = cell.attr('text/textWrap/text')
            const elem = view.container.querySelector('.x6-edit-text')
            if (elem == null) { return }
            cell.attr('text/style/display', 'none')
            if (elem) {
                elem.style.display = ''
                elem.contentEditable = 'true'
                elem.innerText = ""
                elem.focus()
            }
            const onBlur = () => {
                cell.attr('text/textWrap/text', elem.innerText)
                cell.attr('text/style/display', '')
                elem.style.display = 'none'
                elem.contentEditable = 'false'
            }
            elem.addEventListener('blur', () => {
                onBlur()
                elem.removeEventListener('blur', onBlur)
            })
        })
        graph.on(
            'node:mouseenter',
            FunctionExt.debounce(() => {
                const ports = container.querySelectorAll(
                    '.x6-port-body'
                )
                this.showPorts(ports, true)
            }),
            500
        )

        graph.on('node:mouseleave', () => {
            const ports = container.querySelectorAll(
                '.x6-port-body'
            )
            this.showPorts(ports, false)
        })

        graph.on('graph:mouseenter', ({ e }) => {
            e.currentTarget.style.cursor = 'default'
        })
        graph.on('selection:changed', (args) => {
            args.added.forEach((cell) => {
                if (cell.isNode()) {
                    cell.attr('body', {
                        fill: '#ffd591',
                        stroke: '#ffa940',
                    })
                } else {
                    cell.attr('line/stroke', '#ffa940')
                }
            })
            args.removed.forEach((cell) => {
                if (cell.isNode()) {
                    cell.attr('body', {
                        fill: 'rgba(95,149,255,0.05)',
                        stroke: '#5F95FF',
                    })
                } else {
                    cell.attr('line/stroke', this.edgeColor)
                }
            })
        })
        // graph.on('node:collapse', ({ node, e }) => {
        //     e.stopPropagation()
        //     node.toggleCollapse()
        //     const collapsed = node.isCollapsed()
        //     const cells = node.getDescendants()
        //     cells.forEach((n) => {
        //         if (collapsed) {
        //             n.hide()
        //         } else {
        //             n.show()
        //         }
        //     })
        // })

        graph.bindKey('Delete', () => {
            const cells = graph.getSelectedCells()
            if (cells.length) {
                graph.removeCells(cells)
            }
        })


    }
    showPorts (ports, show) {
        for (let i = 0, len = ports.length; i < len; i = i + 1) {
            ports[i].style.visibility = show ? 'visible' : 'hidden'
        }
    }
    graph_FromJSON(data){
        this.graph.fromJSON(data)
    }
    /**
     * 将模板节点添加到指定的群组中。
     * @param nodes:[node]节点数组
     * @param groupName:String群组名
     */
    stencil_load(nodes,groupName){
        this.stencil.load(nodes, groupName)
    }
    createNode(node){
        this.graph.createNode(node)
    }
}